﻿using ChineseCalendar;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Xunit;
using Xunit.Abstractions;

namespace XUnitTester
{
    public class UnitTestFestival
    {
        private readonly ITestOutputHelper Output;

        public UnitTestFestival(ITestOutputHelper tempOutput)
        {
            this.Output = tempOutput;
        }
        [Fact]
        public void Test()
        {
            var type = typeof(Festival);
            var ass = type.Assembly;
            var types = ass.GetTypes().Where(x => x.IsClass && !x.IsAbstract && x.IsSubclassOf(type)).ToList();

            var festivals2 = new List<Festival>();
            foreach(var item in types)
            {
                var ps = item.GetFields(BindingFlags.Static | BindingFlags.Public).Where(x => x.FieldType.IsSubclassOf(type));
                var vals = ps.Select(x => x.GetValue(null)).OfType<Festival>();
                if(vals.Any())
                {
                    festivals2.AddRange(vals);
                }
            }


            var festivals = new List<Festival>
            {
                ChineseFestival.SpringFestival,
                ChineseFestival.LanternFestival,
                ChineseFestival.DragonHeadraisingDay,
                ChineseFestival.DragonBoatFestival,
                ChineseFestival.QixiFestival,
                ChineseFestival.GhostFestival,
                ChineseFestival.MidAutumnFestival,
                ChineseFestival.DoubleNinthFestival,
                ChineseFestival.NewYearsEve,

                GregorianFestival.NewYearsDay,
                GregorianFestival.ArborDay,
                GregorianFestival.TheTombWeepingDay,
                GregorianFestival.InternationalWorkersDay,
                GregorianFestival.TheNationalDay,
            };

            Assert.Equal(festivals.Count(), festivals2.Count());

            Assert.All<Festival>(festivals, item =>
            {
                Output.WriteLine(item.Name + " -- " + item.Description);
                var last = item.GetLastDate(DateTime.Today, false);
                Output.WriteLine($"上一个{item.Name} 在 {last:yyyy-MM-dd}");
                var next = item.GetNextDate(DateTime.Today, true);
                Output.WriteLine($"下一个{item.Name} 在 {next:yyyy-MM-dd}");
            });
        }


        [Fact]
        public void TestFixFestival()
        {
            var fes = new FixDateFestival("大阅兵", 2015, 9, 3, "抗战暨反法西斯胜利70周年大阅兵");
            Output.WriteLine(fes.Name + " -- " + fes.Description);
            Output.WriteLine($"{fes.FirstYear}-{fes.Month}-{fes.Day}");
            var last = fes.GetLastDate(DateTime.Today, false);
            Output.WriteLine($"上一个{fes.Name} 在 {last:yyyy-MM-dd}");
            var next = fes.GetNextDate(DateTime.Today, true);
            Output.WriteLine($"下一个{fes.Name} 在 {next:yyyy-MM-dd}");
        }

        [Fact]
        public void TestBirthday()
        {
            //TestBirstday("wz", 1988, 3, 8);
            TestBirstday("李五月", 2017, 5, 12);
            //TestBirstday("ljn", 2019, 6, 30);
            //TestBirstday("lpz", 1984, 7, 26);
        }
        private void TestBirstday(string name, int year, int month, int day)
        {
            var fes = new GregorianFestival(name, month, day, year, "生日");
            Output.WriteLine($"{fes.Name} {fes.Description} :{fes.FirstYear}-{fes.Month}-{fes.Day}");
            //DateTime? date = DateTime.Today;
            //while(true)
            //{
            //    date = fes.GetLastDate(date, false);
            //    if(!date.HasValue)
            //    {
            //        break;
            //    }

            //    var cdate = ChineseDate.From(date.Value);
            //    Output.WriteLine($"上一个{ fes.Name} 在 {date:yyyy-MM-dd} 农历{cdate}");
            //}
            //date = DateTime.Today;
            //while(true)
            //{
            //    date = fes.GetNextDate(date, false);
            //    if(!date.HasValue || date.Value.Year > 2050)
            //    {
            //        break;
            //    }
            //    var cdate = ChineseDate.From(date.Value);
            //    Output.WriteLine($"下一个{ fes.Name} 在 {date:yyyy-MM-dd} 农历{cdate}");
            //}
            var first = fes.First;
            var cfirst = ChineseDate.From(first.Value);
            var cfes = new ChineseFestival(name, cfirst.Month, cfirst.Day, cfirst.Year, "农历生日");
            Output.WriteLine($"{cfes.Name} {cfes.Description} :{cfes.FirstYear}-{cfes.Month}-{cfes.Day}");
            DateTime? date = first;
            DateTime? cdate = cfirst.ToDate();
            var index = 0;
            while(true)
            {
                try
                {
                    index++;
                    date = fes.GetNextDate(date, false);
                    cdate = cfes.GetNextDate(cdate, false);
                    var date2 = ChineseDate.From(date.Value);
                    var cdate2 = ChineseDate.From(cdate.Value);
                    if(index % 5 == 0)
                    {
                        Output.WriteLine($"{fes.Name} {index}岁{fes.Description}：{date:yyyy-MM-dd dddd} 农历{date2}");
                        Output.WriteLine($"{cfes.Name} {index}岁{cfes.Description}：{cdate:yyyy-MM-dd dddd} 农历{cdate2}");
                    }
                    if(!date.HasValue || index > 100)
                    {
                        break;
                    }
                }
                catch(Exception ex)
                {
                    Output.WriteLine("超出计算范围：" + ex.Message);
                    break;
                }
            }

            //if(first != null)
            //{
            //    var date = first;
            //    var cdate = ChineseDate.From(date.Value);
            //    var index = 0;
            //    while(true)
            //    {
            //        try
            //        {
            //            var cdate2 = ChineseDate.From(date.Value);
            //            if(cdate2.Month == cdate.Month && cdate2.Day == cdate.Day)
            //            {
            //                Output.WriteLine($"{fes.Name} {index}岁生日：{date:yyyy-MM-dd dddd} 农历{cdate2}");
            //            }
            //            date = fes.GetNextDate(date, false);
            //            if(!date.HasValue || index > 100)
            //            {
            //                break;
            //            }
            //            index++;
            //        }
            //        catch(Exception ex)
            //        {
            //            Output.WriteLine("超出计算范围：" + ex.Message);
            //            break;
            //        }
            //    }
            //}
        }
    }
}
